#
# Copyright 2010 Steve Leach
# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
#

from google.appengine.ext import db
from datetime import date, datetime
from formatting import format_thousands

class EveOperation(db.Model):
	
	name = db.StringProperty(required=True)
	fc = db.StringProperty()
	corp_id = db.StringProperty()
	corp_name = db.StringProperty()
	pilots = db.StringListProperty(required=True, default=[])
	op_type = db.StringProperty(default='PvE')
	isk = db.IntegerProperty(default=0)
	op_date = db.DateProperty(auto_now_add=True)
	pay_date = db.DateTimeProperty()
	op_time = db.DateTimeProperty(auto_now_add=True,indexed=True)
	system = db.StringProperty()
	locked = db.BooleanProperty(required=True, default=False)
	paid = db.BooleanProperty(required=True, default=False)
	notes = db.TextProperty()
	deleted_op = db.BooleanProperty(required=True, default=False)
	site_type = db.StringProperty()
	ancient_coord_count = db.IntegerProperty(default=0)
	neural_net_count = db.IntegerProperty(default=0)
	data_lib_count = db.IntegerProperty(default=0)
	drone_ai_count = db.IntegerProperty(default=0)
	salvage_isk = db.IntegerProperty(default=0)
	pay_strategy = db.IntegerProperty(default=3)
	site_count = db.IntegerProperty(default=1)
	corp_tax = db.IntegerProperty(default=15)
	fc_payout = db.IntegerProperty(default=150)
	
	def pilot_isk(self):
		if self.pay_strategy == 3:
			return (self.isk - self.corp_isk()) / (len(self.pilots)-1+(self.fc_payout/100.0))
		elif self.pay_strategy == 2:
			return self.isk * 0.5 / (len(self.pilots)+0.5)
		elif self.pay_strategy == 1:
			return self.isk * 0.92 / (len(self.pilots)+0.5)
		else:
			if len(self.pilots) > 0:
				return self.isk * 0.9 / len(self.pilots)
			else:
				return 0
			
	def fc_isk(self):
		if self.pay_strategy == 3:
			return self.pilot_isk() * self.fc_payout / 100
		if self.pay_strategy == 2:
			return self.pilot_isk() * 1.5
		if self.pay_strategy == 1:
			return self.pilot_isk() * 1.5
		else:
			return self.isk * 0.02 + self.pilot_isk()
		
	def corp_isk(self):
		if self.pay_strategy == 3:
			return self.isk * self.corp_tax / 100
		elif self.pay_strategy == 2:
			return self.isk * 0.5
		else:
			return self.isk * 0.08

	def op_isk_000(self):
		return format_thousands(self.isk)

	def fc_isk_000(self):
		return format_thousands(int(self.fc_isk()))

	def corp_isk_000(self):
		return format_thousands(int(self.corp_isk()))

	def pilot_isk_000(self):
		return format_thousands(int(self.pilot_isk()))

	def add_pilot(self, pilot_name):
		if pilot_name in self.pilots:
			raise Exception('Pilot already on op')
		self.pilots.append(pilot_name)

	def pilot_details(self):
		results = []
		for pilot_name in self.pilots:
			p = Pilot.gql("WHERE char_name = :1", pilot_name).get()
			if not p:
				p = Pilot()
				p.char_name = pilot_name
			results.append(p)
		return results
		
	def fc_id(self):
		pilot = Pilot.gql("WHERE char_name = :1", self.fc).get()
		if pilot:
			return pilot.char_id
		else:
			return "-1"

	def calc_op_isk(self, pilot):
		if self.salvage_isk > 0:
			isk = self.salvage_isk
			isk = isk + self.ancient_coord_count * pilot.ancient_coord_isk
			isk = isk + self.neural_net_count * pilot.neural_net_isk
			isk = isk + self.data_lib_count * pilot.data_lib_isk
			isk = isk + self.drone_ai_count * pilot.drone_ai_isk
			self.isk = isk

	def age_str(self):
		age = datetime.now() - self.op_time
		if age.days > 0:
			return str(age.days) + "d"
		elif age.seconds > 3600: 	# more than an hour
			return str(age.seconds/3600) + "h"
		elif age.seconds > 60:
			return str(age.seconds/60) + "m"
		else:
			return str(age.seconds) + "s"

class PaymentStrategy(db.Model):
	corp_id = db.StringProperty(required=True)
	strat_num = db.IntegerProperty(required=True)
	tax_rate = db.IntegerProperty(required=True, default=0)
	fc_share = db.IntegerProperty(required=True, default=100)	# Proportion of a standard pilot share
	fc_rate = db.IntegerProperty(required=True, default=0)		# Proportion of the total op ISK
	notes = db.TextProperty()

class PilotRole(db.Model):
	op_id = db.IntegerProperty(required=True, indexed=True)
	pilot_name = db.StringProperty(required=True, indexed=True)
	role = db.StringProperty(required=True)
	op_date = db.DateProperty()

class AssistType(db.Model):
	name = db.StringProperty(required=True)

class Assist(db.Model):
	op_ref = db.ReferenceProperty(required=True, indexed=True)
	pilot = db.StringProperty(required=True, indexed=True)
	assist_kind = db.StringProperty(required=True, indexed=True)
	quantity = db.IntegerProperty(default=0)
	timestamp = db.DateTimeProperty(auto_now_add=True)
	assigned_to = db.StringListProperty(required=True, default=[])

class Pilot(db.Model):
	
	char_name = db.StringProperty()
	char_id = db.StringProperty(default='-1')
	stylesheet = db.StringProperty(required=True, default='ingame')
	ancient_coord_isk = db.IntegerProperty(default=0)
	neural_net_isk = db.IntegerProperty(default=0)
	data_lib_isk = db.IntegerProperty(default=0)
	drone_ai_isk = db.IntegerProperty(default=0)
	is_main = db.BooleanProperty(required=True, default=True)
	alts = db.StringListProperty(required=True, default=[])
	last_op = db.DateTimeProperty()
	corp_id = db.StringProperty()
	google_account = db.StringProperty()
	is_director = db.BooleanProperty(required=True, default=False)
	is_dev = db.BooleanProperty(required=True, default=False)
	main_char = db.StringProperty()
	corp_name = db.StringProperty()
	payop_next = db.StringProperty(default='this')
	

def get_main_name(pilot_name):
	pilot = Pilot.gql('WHERE char_name = :1', pilot_name).get()
	if pilot:
		if pilot.main_char:
			pilot_name = pilot.main_char
	return pilot_name

def update_pilot_last_ops():
	pilot_last_ops = {}	
	for op in EveOperation.all():
		for pilot_name in op.pilots:
			if not pilot_name in pilot_last_ops:
				pilot_last_ops[pilot_name] = op.op_time
			elif op.op_time > pilot_last_ops[pilot_name]:
				pilot_last_ops[pilot_name] = op.op_time

	for pilot_name, last_time in pilot_last_ops.iteritems():
		q = Pilot.gql("Where char_name = :1", pilot_name)
		if q.count() > 0:
			pilot = q.get()
			pilot.last_op = last_time
			pilot.put()

class MultiPay(db.Model):
	description = db.StringProperty()

class Corp(db.Model):
	corp_id = db.StringProperty()
	corp_name = db.StringProperty()
	prime = db.BooleanProperty(required=True, default=False)
	ave_op_isk = db.IntegerProperty()
	op_tax_rate = db.FloatProperty()
	op_fc_bonus = db.FloatProperty()

class WaitingPilot(db.Model):
	pilot_name = db.StringProperty(required=True,indexed=True)
	location = db.StringProperty()
	waiting_since = db.DateTimeProperty(auto_now_add=True,indexed=True)
	capability = db.StringProperty()

class SiteSig(db.Model):
	system = db.StringProperty(required=True)
	sig_code = db.StringProperty(required=True)
	site_type = db.StringProperty()
	time_added = db.DateTimeProperty(auto_now_add=True)
	expired = db.BooleanProperty(required=True,default=False)
	started = db.BooleanProperty(required=True,default=False)
	expires_day = db.StringProperty()


